//
//  SRPacket.m
//  sr01sdkProject
//
//  Created by  on 2022/5/7.
//

#import "CAPacket.h"
#import "CAHistoryData.h"
#import "CAsDKTool.h"
#import "CAHistoryDataSR03.h"
#import "CAHistoryDataNALG.h"
#import "CARingSDK.h"
#import "CAnAlgGrandActivity.h"
#import "CAnAlgAutoDetecActivity.h"
#import "CAnAlgSleep.h"
#import "CAnAlgRealMeasure.h"
#import "CAnAlgSkinTempAsleep.h"
#import "CAnAlgRltExerData.h"
#import "CAnAlgActIntnstyHisData.h"
#import "CAnAlgDevErrLog.h"
#import "CAnAlgGrandActivity2.h"

const uint8_t CACMD_HEAD = 0XFE;  // 命令包头
const uint8_t CADATA_PKG_SIZE = 20; //字节
const uint8_t CAINDEX_PKG_HEAD = 0; //第一字节
const uint8_t CAINDEX_CRC = CADATA_PKG_SIZE - 1;

@implementation CAPacket
{
    NSUInteger _historyCount;
    CAsDKTool *_sdkTool;
}

-(instancetype)init
{
    if (self = [super init]) {
        _sdkTool = [[CAsDKTool alloc]init];
        [self resetChargeState];
    }
    return self;
}

-(void)resetTranslatingHistoryState
{
    _historyCount = 0;
    // 传输完成
    _isTranslatingHistory = NO;
    [self.hisTimer invalidate];

}

/// 获取心率血氧数据
/// @param both NO 单心率模式 YES 心率血氧模式
/// @param isOpen 开关
+(NSData *)packGetOxygenHrvBoth:(BOOL)both IsOpen:(BOOL)isOpen
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_GET_OXYGEN_HRV;
    
    // 开关
    bytes[2] = isOpen;
    if (both) {
        bytes[3] = 0X01; // 1=心率血氧全开
    }
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}


/// 关机
+(NSData *)packShutDown
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SHUT_DOWN;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

/// 关机
+(NSData *)packReboot
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_REBOOT;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

//PACK_CMD_BATTERY
/// 关机
+(NSData *)packBattery
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_BATTERY;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packGetSteps
{
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_GET_STEPS;
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packGetTemperature
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_GET_TEMPERATURE;

    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)PackReset
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FACTORY_RESET;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}
// 下发获取设备信息5
+(NSData *)PackGetDevInfoFive
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_GET_DEVICEINFO_5;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

// 下发设置测量时长 单位 秒 8-180s
+(NSData *)PackSetHrMeasureDuration:(NSInteger)seconds
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_SET_HR_MEASURE_DURATION;
    
    if (seconds < 8) {
        seconds = 8;
    }
    
    if (seconds > 180) {
        seconds = 180;
    }
    
    bytes[2] = seconds & 0xFF;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}


///
/// - Parameters:
///   - on: 开关
///   - sampleRate: 采样率 默认 512
///   - clockSource: 内部时钟源 默认 1
///   - ecgPgaGain: 默认 2
///   - isFilterWave: YES = 算法滤波数据 NO = 原始数据
+(NSData *)PackEcgMeasure:(BOOL)on SampleRate:(uint16_t)sampleRate InnerClockSource:(uint8_t)clockSource EcgPgaGain:(uint8_t)ecgPgaGain DispSrc:(BOOL)isFilterWave
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_ECG;
    
  
    bytes[2] = on & 0xFF;
    if (on) {
        // 采样率
        memcpy(bytes+3, (void *)(&sampleRate), sizeof(uint16_t));

        bytes[5] = clockSource;
        bytes[6] = ecgPgaGain;
        
        bytes[7]  = isFilterWave ? 1 : 0;
    }



    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)PackEcgAndPpgMeasure:(BOOL)on
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_ECG_PPG;
    
  
    bytes[2] = on & 0xFF;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)PackSetStepCountingThreshold:(uint8_t)threshold
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_SET_STEP_THRESHOLD;
    
  
    bytes[2] = threshold;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

#pragma mark --AES

/// 开始厂家验证
+(NSData *)packStartAes
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_START_MANUFACT_CER;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}


/// 下发解密原文
+(NSData *)packSendR2:(NSData *)r2
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_MANUFACT_SEND_R2;
    
    uint8_t * r2Bytes = (uint8_t *)[r2 bytes];
    
    memcpy(bytes+2, (void *)(r2Bytes), r2.length);
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    NSData *cmdData =  [NSData dataWithBytes:bytes length:20];
    return cmdData;
}


/// 打包修改的蓝牙广播名
/// - Parameter name: 蓝牙广播名
+(NSData *) packModifyBRcastName:(NSString *)name HideMac:(BOOL)hideMac
{
    
    if (name.length> 16) {
        name = [name substringWithRange:NSMakeRange(0, 16)];
    }
    
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_MODIFY_BRCAST_NAME;
    // 从 2 开始
    
    const char *temp = [name UTF8String];
    
    strncpy((void *)(bytes + 2), temp, 16);
 
    bytes[18] = hideMac ? 1: 0;
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    NSData *cmdData =  [NSData dataWithBytes:bytes length:20];
    return cmdData;
}


+(NSData *)packSN {
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SN;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packDevInfo {
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_DEVICE_INFO;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}

+(NSData *)packTimeSync:(NSDate *)date
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SYNC_TIME;
    
//    NSDate *date = [NSDate date];
//    date = [NSDate dateWithTimeIntervalSince1970:[date timeIntervalSince1970] - 24 * 3600];
    // 时间戳
    *((uint32_t *)(bytes + 2)) = (uint32_t)([date timeIntervalSince1970]);
    
    NSCalendar *calendar  = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; //使用公历
    //[NSCalendar currentCalendar];
    
    NSDateComponents *components = [calendar components:NSUIntegerMax fromDate:date];
    *((uint16_t *)(bytes + 6)) = (uint16_t)(components.year);
    bytes[8] = (uint8_t)(components.month);
    bytes[9] = (uint8_t)(components.day);
    bytes[10] = (uint8_t)(components.hour);
    bytes[11] = (uint8_t)(components.minute);
    bytes[12] = (uint8_t)(components.second);
    
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}

+(NSData *)packHistoryCount {
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_HIS_COUNT;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

/// 下发 led单色测量
/// - Parameters:
///   - on: 1开,0关
///   - ledColor: 0-绿灯,1-红灯,2-红外
///   - autoAdjBri: 是否自动调光
///   - current: 电流 0-255
///   - sampleRate: 0-25hz, 1-50hz, 2-100hz
+(NSData *)packLedMeasure:(BOOL)on LedColor:(uint8_t)ledColor AutoAdjBri:(BOOL)autoAdjBri Current:(uint8_t)current SampleRate:(uint8_t)sampleRate
{
    // PACK_CMD_FUNCTIN_LED_MEA
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_LED_MEA;
    
    bytes[2] = on ? 1: 0;
    
    bytes[3] = ledColor;
    
    bytes[4] = current;
    
    bytes[5] = autoAdjBri ? 1: 0;
    
    bytes[6] = sampleRate;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packBindDevice:(BOOL)bind
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_BIND;
    
    bytes[2] = bind ? 1 : 0 ;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}

+(NSData *)packOEMSwitch:(BOOL)on
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_OEM_SWITCH;
    
    bytes[2] = on ? 1 : 0 ;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}


+(NSData *)packSOSSettingDoubleTapTimes:(uint8_t)doubleTapTimes
                                       SingleTapInterval:(uint8_t)singleTapInterval TapDetectionThreshold:(uint8_t)tapDetectionThreshold
           DoubleTapEffectStartTime:(uint8_t)doubleTapEffectStartTime DoubleTapEffectEndTime:(uint8_t)doubleTapEffectEndTime Open:(BOOL)sosOpen
{
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SOS_SETTING;
    
    bytes[2] = sosOpen ? 1 : 0; // sos 开关
    
    if (doubleTapTimes < 1) {
        doubleTapTimes = 1;
    }else if (doubleTapTimes > 10) {
        doubleTapTimes = 10;
    }
    
    bytes[3] = doubleTapTimes;
    
    bytes[4] = singleTapInterval; //两次单击间隔
    if (tapDetectionThreshold > 63) {
        tapDetectionThreshold = 63;
    }
    bytes[5] = tapDetectionThreshold;
    if (doubleTapEffectEndTime <= doubleTapEffectStartTime) {
        doubleTapEffectEndTime = doubleTapEffectStartTime + 1;
    }
    bytes[6] = doubleTapEffectStartTime;
    bytes[7] = doubleTapEffectEndTime;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}

+(NSData *)packSettingOxygenMeasure:(NSUInteger)startHor
                           StartMin:(NSUInteger)startMin
                           StartSec:(NSUInteger)startSecond
                             Endhor:(NSUInteger)endHor
                             EndMin:(NSUInteger)endMin
                             EndSec:(NSUInteger)endSec
                           Interval:(NSUInteger)interval IsOn:(BOOL)isOn
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SET_OXYGEN_MEASURE;
    
    bytes[2] = isOn ? 1 : 0; // 开关
    
    bytes[3] = (uint8_t)startHor;
    bytes[4] = (uint8_t)startMin;
    bytes[5] = (uint8_t)startSecond;
    
    bytes[7] = (uint8_t)endHor;
    bytes[8] = (uint8_t)endMin;
    bytes[9] = (uint8_t)endSec;
    
    *((uint16_t *)(bytes + 11)) = (uint16_t)(interval); //间隔 分钟
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
    
}

+(NSData *)packSettingHeartRateMeasurInterval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval IsOn:(BOOL)isOn
{
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SET_HR_TEMP_MEASURE;
    bytes[2] = isOn ? 1 : 0; // 开关
    
    *((uint16_t *)(bytes + 10)) = (uint16_t)hrInterval;
    *((uint16_t *)(bytes + 12)) = (uint16_t)skinTemperatureInterval;
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packSportMode:(NSUInteger)startHor StartMin:(NSUInteger)startMin
                StartSec:(NSUInteger)startSecond Endhor:(NSUInteger)endHor
                  EndMin:(NSUInteger)endMin EndSec:(NSUInteger)endSec
              HrIntreval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval
                BloodOxygenInterval:(NSUInteger)oxygeninterval
                    IsOn:(BOOL)isOn
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SET_SPORT_MODE;
    bytes[2] = isOn ? 1 : 0; // 开关
    
    bytes[3] = (uint8_t)startHor;
    bytes[4] = (uint8_t)startMin;
    bytes[5] = (uint8_t)startSecond;
    
    
    
    bytes[7] = (uint8_t)endHor;
    bytes[8] = (uint8_t)endMin;
    bytes[9] = (uint8_t)endSec;
    
    *((uint16_t *)(bytes + 11)) = (uint16_t)hrInterval;
    *((uint16_t *)(bytes + 13)) = (uint16_t)oxygeninterval;
    *((uint16_t *)(bytes + 15)) = (uint16_t)skinTemperatureInterval;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}


// 清空设备历史
+(NSData *)packClearHistory {
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_CLEAR_HIS_DATA;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packSoprtMode:(BOOL)start
           ValueINterval:(uint16_t)valInterval
                Duration:(uint16_t)durationMIn
               SportType:(SDKSportType)spType
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SPORT_MODE;
    
    bytes[2] = start;
    
    *((uint16_t *)(bytes + 3)) = valInterval; // 取值间隔
    
    *((uint16_t *)(bytes + 5)) = durationMIn; // 持续时间

    *((uint16_t *)(bytes + 7)) = spType & 0XFF; // 运动类型
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packHistoryData {
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_HIS_DATA;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

#pragma mark -- CM
// 设置用户信息
+(NSData *)packSetUsrInfoToDev:(NSUInteger)gender Age:(NSUInteger)ageYear Height:(NSUInteger)height Weight:(NSUInteger)weight IsGet:(BOOL)isGet;
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_SET_USERINFO;
    
    if (!isGet) {
        bytes[2] = 1; // 1 设置
        
        bytes[3] = gender;  // 性别
        bytes[4] = ageYear; //年龄
        
        // 5,6 身高 毫米单位
        *((UInt16 *)(bytes + 5)) = height;
        bytes[7] = weight; // 体重
    }
    if (isGet) {
        // 获取
        bytes[2] = 0; // 0 获取
    }
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];

    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packGetLastActivity
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_GET_LAST_ACTIVITY;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];

    return  [NSData dataWithBytes:bytes length:20];
}

// 清除活动历史数据
+(NSData *)packCleanActivityHis
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_CLEAN_ACTIVITY_DATA;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];

    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packGetHisCntOfActivAndSwimAndSleep
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_GET_HISCNT_ACT_SWIM_SLEEP;
    
    bytes[2] = 1; // 1 全部数据 0 部分数据
    
    bytes[3] = 0xFF;
    bytes[4] = 0xFF;
    bytes[5] = 0xFF;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];

    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packGetHisDataOfActivAndSwimAndSleep:(uint32_t)limitUUid {
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    // 命令字
    bytes[1] =  PACK_CMD_FUNCTIN_GET_HIS_DATA_ACT_SWIM_SLEEP;
    if (limitUUid == 0) {
        bytes[2] = 1; // 1 全部数据 0 部分数据

    } else {
        bytes[2] = 0; // 1 全部数据 0 部分数据
        uint32_t uuidMax = limitUUid & 0XFFFFFF;
        bytes[3] = *((uint8_t*)(&uuidMax) +0);
        bytes[4] = *((uint8_t*)(&uuidMax) +1);
        bytes[5] = *((uint8_t*)(&uuidMax) +2);
    }
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];

    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packCmDura:(BOOL)isSet Type:(uint32_t)type  DuraNoSlp:(uint32_t)meaduraNoSleep  IntervNoslp:(uint32_t)meaIntervNoSleep DuraInSlp:(uint32_t)meaDuraInSleep IntervInslp:(uint32_t)meaIntervInSlp
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    // 命令字
    bytes[1] =  PACK_CMD_FUNCTIN_CM_MEA_DURA_AND_TIME;
    
    bytes[2] = isSet ? 1 : 0 ;
    
    bytes[3] = (uint8_t)type;
    
    if (isSet) {
        bytes[4] = (uint8_t)meaduraNoSleep;// 非睡眠的测量时长
        
        *((uint16_t *)(bytes + 5)) = (uint16_t)meaIntervNoSleep;// 非睡眠的测量间隔
        
        bytes[7] = (uint8_t)meaDuraInSleep;// 睡眠的测量时长
        
        *((uint16_t *)(bytes + 8)) = (uint16_t)meaIntervInSlp;// 睡眠的测量间隔
        
    }
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];

    return  [NSData dataWithBytes:bytes length:20];

}

+(NSData *)packCMexercise:(uint8_t)subCmd ExerciseType:(uint8_t)execType PoolSize:(uint8_t)sizeType HeartrateStorageInterval:(uint16_t)hrStoreInterv DurationMins:(uint16_t)duraMins
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    // 命令字
    bytes[1] =  PACK_CMD_FUNCTIN_START_CM_EXER;
    
    bytes[2] = subCmd;
    
    bytes[3] = execType;
    if(subCmd == 1) { // 0 关, 1 开始, 2 暂停, 3 恢复
        *((uint16_t *)(bytes+4)) = hrStoreInterv;// 心率存储间隔
        
        bytes[6] = sizeType;
        
        *((uint16_t *)(bytes+7)) = duraMins; // 时长, 分钟
    }
 
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];

    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packexerciseRealReportSwitch:(BOOL)on
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    // 命令字
    bytes[1] =  PACK_CMD_FUNCTIN_EXER_REALTM_REPORT;
    
    bytes[2] = on ? 1 : 0; // 1 开启 , 0 关闭
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];

    return  [NSData dataWithBytes:bytes length:20];

}

// 设置/获取 设备的算法类型
+(NSData *)packDeviceAlgorithm:(BOOL)isSet Type:(uint8_t)algorithmType
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    // 命令字
    bytes[1] =  PACK_CMD_FUNCTIN_CM_DEVICE_ALGORITHM;
    
    bytes[2] = isSet ? 1 : 0 ;// 1 设置,0获取
    
    bytes[3] = algorithmType;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];

    return  [NSData dataWithBytes:bytes length:20];

    
}
+(NSData *)packGetLastActivity_2
{
    
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CACMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_GET_LAST_ACTIVITY_2;
    
    // crc
    bytes[CAINDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:CADATA_PKG_SIZE]];

    return  [NSData dataWithBytes:bytes length:20];
}
/// 解包
/// @param data 蓝牙原始包
-(void)receiveData:(NSData *)data {
    NSUInteger length = data.length;
    
    if (length != 20) {
        DebugNSLog(@"sdk recv data > 20, data:%@", data);
        return;
    }
    
    uint8_t *dataBytes = (uint8_t *)[data bytes];
    if (dataBytes[0] != CACMD_HEAD) {
        return;
    }
    
//    DebugNSLog(@"recv pack tag :%X", dataBytes[1]);
    
    switch (dataBytes[1]) {
        case DEVICE_RESPONSE_OXYGEN_HRV: // 血氧 hrv上报  0x83
        {
            uint8_t status = dataBytes[6];// 0未测量 1测量中 2数据有效
            
            uint8_t oxygen = dataBytes[2];
            uint8_t heartRate = dataBytes[3];
            NSInteger hrv = *((uint16_t *)(dataBytes + 4));
            DebugNSLog(@"血氧 %d hrv %ld 心率 %d", oxygen, (long)hrv, heartRate);
//            float hrv_f = sqrtf(hrv * 1.0);
            
            NSNumber *cbHr, *cbHrv, *cbOxygen;
            cbHrv = @(hrv);
            // 回调血氧
            if (oxygen > 0 && oxygen <= 100) {
                cbOxygen = @(oxygen);
            }
            // 回调心率
            if (heartRate >0 && heartRate <= 200) {
                cbHr = @(heartRate);
            }
            // 回调hrv
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceRealtimeHRV:BloodOxygen:HeartRate:Status:)] ) {
                [self.dataDelegate stkeyFobServiceRealtimeHRV:cbHrv  BloodOxygen:cbOxygen HeartRate:cbHr Status:status];
            }
            
            
            
        }
            break;
        case DEVICE_RESPONSE_STEP_DATA: // 0X84 计步数据
        {
            BOOL LIS2DS12 = NO;
            uint16_t steps = *(uint16_t *)(dataBytes + 2);
            if (dataBytes[4] == 1) {
                LIS2DS12 = YES;
            }
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceRealtimeSteps:IsDeviceFix:)] ) {
                [self.dataDelegate stkeyFobServiceRealtimeSteps:@(steps) IsDeviceFix:LIS2DS12];
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_TEMPRETRUE_DATA:   // 0X85 体表温度
        {
            uint16_t temp = *(uint16_t *)(dataBytes + 2);
            
            float callbackTemp = (temp + 200) / 10.0f;
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceRealtimeTemperaure:)] ) {
                [self.dataDelegate stkeyFobServiceRealtimeTemperaure:@(callbackTemp)];
            }
        }
            break;
        case DEVICE_RESPONSE_RESPCMD: // 设备收包应答
        {
            uint8_t cmd = dataBytes[2];   // 返回下发命令
            uint8_t excuteRes = dataBytes[4]; // 执行结果, 0 = 正确
            uint8_t reason = dataBytes[5]; // 错误原因
            
            CA_CMD_EXECTE_ERROR_REASON rea = reason;
            
//            DebugNSLog(@"device recv cmd  :%X  excute cmd res:%X", cmd, excuteRes);

            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceSendCmdExcute: Succ:Reason:Data:)] ) {
                [self.dataDelegate stkeyFobServiceSendCmdExcute:cmd Succ:excuteRes == 0 Reason:rea Data:data];
            }
            // 历史同步 1 的防重入还原
            if (excuteRes != 0 && cmd ==  PACK_CMD_HIS_DATA)
            {
                [self resetTranslatingHistoryState];
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_BATTERY_LEVEL:
        {
            uint16_t voltage = ((uint16_t *)dataBytes)[1]; // 电压
            uint8_t isCharging = dataBytes[4];
            uint8_t percent = dataBytes[5]; // sr09 新增百分比
            
            
            // stkeyFobServiceBatteryLevel
            int batteryLevel = 0;
            
            if (percent > 0) {
                batteryLevel = percent;
            } else {
                
                // 2023-7-26 更新
                NSNumber *numBatt = [_sdkTool voltageToBattery:voltage IsCharge:isCharging IsWireness:[CARingSDK instance].currentDevice.isWirenessCharge.boolValue];
                batteryLevel = numBatt.intValue;
                
//                batteryLevel = [SDKTool toBatteryLevel:voltage IsCharge:isCharging IsWireness:[LTSRingSDK instance].currentDevice.isWirenessCharge.boolValue];
            }
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceBatteryLevel:IsCharging:Voltage:)] ) {
                [self.dataDelegate stkeyFobServiceBatteryLevel:(NSInteger)batteryLevel IsCharging:isCharging == 1 Voltage:voltage];
            }
        }
            break;
        case DEVICE_RESPONSE_DEVICEINFO_DATA:// 0X87
        {
            // 设备信息
            
            CADeviceInfo *info = [[CADeviceInfo alloc]initWithData:data];
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceDeviceInfo:)] ) {
                [self.dataDelegate stkeyFobServiceDeviceInfo:info];
            }
            _projectId = info.projectId; // 项目代号 区分什么设备
            
        }
            break;
        case DEVICE_RESPONSE_SN_DATA: // sn号 和其他信息 0x88
        {
            NSString *snString;
            NSData * snData;
            uint8_t *snDataBytes;
            if (_projectId == 0X22) {
                // 日本 pixela sn长度6字节
                snData = [data subdataWithRange:NSMakeRange(2, 8)];
                snDataBytes = (uint8_t *)[snData bytes];
                snString = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x", snDataBytes[0],
                            snDataBytes[1],
                            snDataBytes[2],
                            snDataBytes[3],
                            snDataBytes[4],
                            snDataBytes[5],
                            snDataBytes[6],
                            snDataBytes[7]
                ];
                long long snNUmber = [snString longLongValue];
                snString = [NSString stringWithFormat:@"%lld", snNUmber];
                
            } else {
                // 其他 sn 长度8字节
                snData = [data subdataWithRange:NSMakeRange(2, 8)];
                snDataBytes = (uint8_t *)[snData bytes];
                snString = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x", snDataBytes[0],
                                      snDataBytes[1],
                                      snDataBytes[2],
                                      snDataBytes[3],
                                      snDataBytes[4],
                                      snDataBytes[5],
                                      snDataBytes[6],
                                      snDataBytes[7]];
                long long snNUmber = [snString longLongValue];
                snString = [NSString stringWithFormat:@"%lld", snNUmber];
            }
            
            
            
            
//            NSString *snString = [[NSString alloc] initWithData:snData encoding:NSUTF8StringEncoding];
            
            uint8_t * bytes = (uint8_t *)[data bytes];
            // sos开关
            BOOL isSosOpen = bytes[10] > 0;
            
            UInt8 doubleTapTimes = bytes[11]; // 触发sos的双击次数
            UInt8 singleTapSepTime = bytes[12]; // 两次单击的间隔
            uint8_t tapDetectionThreshold = bytes[13]; //拍击检测阈值
            uint8_t doubleTapEffectStartTime = bytes[14]; // 双击有效起始时间 单位 秒
            uint8_t doubleTapEffectEndTime = bytes[15]; // 双击有效结束时间 单位 秒
            BOOL isBinded = bytes[16] > 0; // 是否绑定

            
            
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceSN:OriginSNData:)] ) {
                [self.dataDelegate stkeyFobServiceSN:snString OriginSNData:snData];
            }
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobService:DoubleTapTimes:SingleTapInterval:TapDetectionThreshold:DoubleTapEffectStartTime:DoubleTapEffectEndTime:Isbinded:)] ) {
                [self.dataDelegate stkeyFobService:isSosOpen
                                    DoubleTapTimes:doubleTapTimes
                                 SingleTapInterval:singleTapSepTime
                             TapDetectionThreshold:tapDetectionThreshold
                          DoubleTapEffectStartTime:doubleTapEffectStartTime
                            DoubleTapEffectEndTime:doubleTapEffectEndTime Isbinded:isBinded];
            }
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceIsBinded:)]) {
                [self.dataDelegate stkeyFobServiceIsBinded:isBinded];
            }
            
            
        }
            break;
            
        case  DEVICE_RESPONSE_HISTORY_COUNT: // 历史数据个数
        {
            if (self.isTranslatingHistory) {
                break; // 防止重入同步
            }
            self.isTranslatingHistory = YES;
            // 记录个数
            uint16_t count = ((uint16_t *)dataBytes)[1];
            _historyCount = count;
            DebugNSLog(@"%@: history count %d", NSStringFromClass([self class]),count);
            // 启动超时
            [self.hisTimer invalidate];
            if (count > 0) {
                __weak typeof(self) weakSelf = self;
                NSTimeInterval interval = 50 * count * 1.0 / 1000; // 每条数据给50毫秒时间
                if (interval < 3) {
                    interval = 3;
                }
                self.hisTimer = [NSTimer scheduledTimerWithTimeInterval:interval repeats:NO block:^(NSTimer * _Nonnull timer) {
                    __strong typeof(weakSelf) strongSelf = weakSelf;
                    if (strongSelf.isTranslatingHistory) {
                        if (strongSelf != nil && [strongSelf.dataDelegate respondsToSelector:@selector(stkeyFobServiceHistoryTimeout)] ) {
                            [strongSelf.dataDelegate stkeyFobServiceHistoryTimeout];
                        }
                        strongSelf->_isTranslatingHistory = NO;
                        strongSelf->_historyCount = 0;
                    }
                    
                    
                }];
            }
          
            // 获取历史数据
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHistoryCount:)] ) {
                [self.dataDelegate stkeyFobServiceHistoryCount:count];
            }
            if (count == 0) {
                // 没数据, 直接回调完成
                self.isTranslatingHistory = NO;
                
                if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHistorySR03Data:IsComplete:)] ) {
                    [self.dataDelegate stkeyFobServiceHistorySR03Data:nil IsComplete:YES];
                }
                
            }
        }
            break;
        case   DEVICE_RESPONSE_HISTORY_DATA: // 历史数据上报 0x82
        {
            // 历史数据
            CAHistoryDataSR03 *hisData_03 =  [[CAHistoryDataSR03 alloc]initWithData:data];
//            SRHistoryData *hisData = [[SRHistoryData alloc] initWithData:data];
            _historyCount = _historyCount - 1;
         
            
            // sr02 格式
//            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHistoryData:IsComplete:)] ) {
//                [self.dataDelegate stkeyFobServiceHistoryData:hisData IsComplete:_historyCount == 0];
//            }
           
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHistorySR03Data:IsComplete:)] ) {
                [self.dataDelegate stkeyFobServiceHistorySR03Data:hisData_03 IsComplete:_historyCount == 0];
            }
            
            if (_historyCount == 0) {
                // 传输完成
                _isTranslatingHistory = NO;
                [self.hisTimer invalidate];
            }
            
        }
            break;
        case DEVICE_RESPONSE_HISTORY_DATA_3:
        case DEVICE_RESPONSE_HISTORY_DATA_2: // 历史数据上报 2 2023-7-19 0x91
        {
            // 历史数据
            CAHistoryDataSR03 *hisData_03 =  [[CAHistoryDataSR03 alloc]initWithData:data];
//            SRHistoryData *hisData = [[SRHistoryData alloc] initWithData:data];
            _historyCount = _historyCount - 1;
        
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHistorySR03Data:IsComplete:)] ) {
                [self.dataDelegate stkeyFobServiceHistorySR03Data:hisData_03 IsComplete:_historyCount == 0];
            }
            
            if (_historyCount == 0) {
                // 传输完成
                _isTranslatingHistory = NO;
                [self.hisTimer invalidate];
            }
            
        }
            break;
        case DEVICE_RESPONSE_HISTORY_DATA_SR28: // 0xC1 CM历史单独格式
        {
            CAHistoryDataNALG *cmHisData = [[CAHistoryDataNALG alloc]initWithData:data];
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:cmHisData];
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_SOS: // sos触发
        {
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceSOShappen)] ) {
                [self.dataDelegate stkeyFobServiceSOShappen];
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_SOS_MEASUREDATA:
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            float temperature = (bytes[2]  + 200) / 10.0f; // 体温
            NSInteger hr = bytes[3] & 0xff; // 心率
            NSInteger oxygen = bytes[4] & 0xff; // 血氧
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceSOSData:HeartRate:BloodOxygen:)] ) {
                [self.dataDelegate stkeyFobServiceSOSData:temperature HeartRate:hr BloodOxygen:oxygen];
            }
        }
            break;
            
        case DEVICE_RESPONSE_MANUFAT_R1: //上报厂家验证 R1
        {
            NSData *r1Data = [data subdataWithRange:NSMakeRange(2, 16)];
//            uint8_t * bytes = (uint8_t *)[data bytes];
//            uint16_t r1 = 0;
//            memcpy((void *)&r1, bytes+2, sizeof(uint16_t)); // 取出设备发来的的R1
            if([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceAESRecvR1:)])
            {
                [self.dataDelegate stkeyFobServiceAESRecvR1:r1Data];
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_MANUFAT_RES: // 上报厂家验证结果:
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
           
            if([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceAESAuthResult:)])
            {
                BOOL succ = bytes[2] > 0;
                [self.dataDelegate stkeyFobServiceAESAuthResult:succ];
            }
            
        }
            break;
        case DEVICE_RESPONSE_HR_MEASURE_DURATION: //上报 测量时长
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            
            uint8_t duretuon = bytes[2]; //心率测量时间 单位 秒
            
            uint32_t pd_threshold = *((uint32_t *)(bytes + 3));// pd 采样阈值
            uint32_t pd_range_1 = *((uint32_t *)(bytes + 7)); // pd 采样值波动范围1
            uint32_t pd_range_2 = *((uint32_t *)(bytes + 11)); // pd 采样值波动范围2
            
            DebugNSLog(@"测量时长 %d , pd阈值 %d, 范围1 %d, 范围2 %d", duretuon, pd_threshold, pd_range_1, pd_range_2);
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHrMeasuDuration:PD_THRESHOLD:PD_RANGE_1:PD_RANGE_2:)]) {
                
                [self.dataDelegate stkeyFobServiceHrMeasuDuration:duretuon PD_THRESHOLD:pd_threshold PD_RANGE_1:pd_range_1 PD_RANGE_2:pd_range_2];
            }
            
            uint8_t stepThreshold = bytes[18]; // 计步阈值
            // stkeyFobServiceCountThreshold
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCountThreshold:)]) {
                
                [self.dataDelegate stkeyFobServiceCountThreshold:stepThreshold];
            }
            
        }
            break;
        case  DEVICE_RESPONSE_ECG_ROW: //0X94,ecg上报
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            void * dataStart = bytes+2;
            
            void *countPoint =  bytes+17;
            uint16_t count = *((uint16_t *)countPoint) & 0XFFFF; // 数据计数
            
            NSMutableArray<NSNumber *> *ecgDataArray = [NSMutableArray new];
            for (int i = 0; i < 5; i++) {
                uint8_t *ecgDataStart =  dataStart + i*3;
                
                uint8_t ecg_data[3] = {0};
                
                
                uint8_t data1 = *ecgDataStart & 0xFF;
                uint8_t data2 = *(ecgDataStart+1) ;
                uint8_t data3 = *(ecgDataStart+2) ;
                
                ecg_data[0] = data3;
                ecg_data[1] = data2;
                ecg_data[2] = data1;
                
                int32_t int32_ecg_data = 0;
                int32_ecg_data = (int32_t)((ecg_data[0]) + (ecg_data[1]<<8) +  (ecg_data[2]<< 16) );

                 if(((ecg_data[2]>> 1) & 0x01) > 0){//负数
                     
                     int32_ecg_data = ((~(int32_ecg_data - 1)) & 0x3ffff) * -1;
                     
                 }


//                uint32_t ecgData =  (data1 << 16) + (data2<<8) + data3;
                [ecgDataArray addObject:@(int32_ecg_data)];
            }
            
            CAEcgData *ecgObj = [[CAEcgData alloc]init];
            ecgObj.type = CAECG_TYPE_ONLY_ECG;
            ecgObj.packCmdHead = DEVICE_RESPONSE_ECG_ROW;
            ecgObj.ecgArray = ecgDataArray;
            ecgObj.idx = count;
            // 回调
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceEcg:)]) {
                
                [self.dataDelegate stkeyFobServiceEcg:ecgObj];
            }
            
        }
            break;
        case  DEVICE_RESPONSE_ECG_PPG_ROW:        // 0X95 ecg+ppg上报
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            void * dataStart = bytes+2;
            
            void *countPoint =  bytes+17;
            uint16_t count = *((uint16_t *)countPoint) & 0XFFFF; // 数据计数
            
            NSMutableArray<NSNumber *> *ecgDataArray = [NSMutableArray new];
            NSMutableArray<NSNumber *> *ppgDataArray = [NSMutableArray new];

            for (int i = 0; i < 3; i++) {
                uint8_t *ecgDataStart =  dataStart + i*5;
                
                uint8_t ppgdata1 = *ecgDataStart & 0xFF;
                uint8_t ppgdata2 = *(ecgDataStart+1) & 0xFF;
                uint8_t ppgdata3 = ((*(ecgDataStart+2) & 0xFF) >> 4) & 0xFF;
                
                int ppgData =  (ppgdata1 << 12) + (ppgdata2<<4) + ppgdata3;
                [ppgDataArray addObject:@(ppgData)];
                
                uint32_t ecgdata1 = (*(ecgDataStart+2) & 0x01) << 16;
                uint8_t ecgdata2 = *(ecgDataStart+3) & 0xFF;
                uint8_t ecgdata3 = *(ecgDataStart+4) & 0xFF;
                
                uint32_t ecg = ecgdata1 + (ecgdata2<<8)&0XFFFF + ecgdata3;
                [ecgDataArray addObject:@(ecg)];
            }
            
            CAEcgData *ecgPpgObj = [[CAEcgData alloc]init];
            ecgPpgObj.type = CAECG_TYPE_ECG_PPG;
            ecgPpgObj.packCmdHead =DEVICE_RESPONSE_ECG_PPG_ROW;
            ecgPpgObj.ecgArray = ecgDataArray;
            ecgPpgObj.ppgArray = ppgDataArray;
            ecgPpgObj.idx = count;
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceEcgAndPPg:)]) {
                
                [self.dataDelegate stkeyFobServiceEcgAndPPg:ecgPpgObj];
            }
            
        }
            break;
        case  DEVICE_RESPONSE_ECG_PPG_FILTER: // 0x96 ecg算法波形上报
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            void * dataStart = bytes+2;
            
            void *countPoint =  bytes+16;
            uint16_t count = *((uint16_t *)countPoint) & 0XFFFF; // 数据计数
            
            NSMutableArray<NSNumber *> *ecgDataArray = [NSMutableArray new];
            for (int i = 0; i < 7; i++) {
                uint8_t *ecgDataStart =  dataStart + i*2;
                
                int16_t ecgData =  *((int16_t *)ecgDataStart);
                
//                uint8_t data1 = *ecgDataStart & 0xFF;
//                uint8_t data2 = *(ecgDataStart+1) & 0xFF;
//               
//
//                uint32_t ecgData =  (data1 << 8) + data2;
                int16_t lowCase = ntohs(ecgData); // 转小端
                [ecgDataArray addObject:@(lowCase)];
            }
            
            CAEcgData *ecgObj = [[CAEcgData alloc]init];
            ecgObj.type = CAECG_TYPE_ONLY_ECG;
            ecgObj.packCmdHead = DEVICE_RESPONSE_ECG_PPG_FILTER;
            ecgObj.ecgArray = ecgDataArray;
            ecgObj.idx = count;
            ecgObj.isAlgorithData = YES; //标记是算法数据
            
            // 回调
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceEcg:)]) {
                
                [self.dataDelegate stkeyFobServiceEcg:ecgObj];
            }
            
        }
            break;
       
        case  DEVICE_RESPONSE_ECG_RESULT: // ecg算法计算结果
        {
            CAEcgAlgorithmResults *result = [[CAEcgAlgorithmResults alloc]initWithData:data];
            
            // 回调
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceEcgResult:)]) {
                
                [self.dataDelegate stkeyFobServiceEcgResult:result];
            }
            
        }
            break;
            
        case DEVICE_RESPONSE_ECG_LEAD_ON:
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            BOOL lead_on = bytes[2];
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceEcgLeadOn:)]) {
                [self.dataDelegate stkeyFobServiceEcgLeadOn:lead_on];
            }
        }
            break;
        case DEVICE_RESPONSE_SR28_MUTI_INFO: // 用户信息上报 CM
        {
            if(dataBytes[2] == PACK_CMD_FUNCTIN_SET_USERINFO) { // 用户信息
                uint8_t * bytes = (uint8_t *)[data bytes];

                NSUInteger gender = bytes[3] & 0XFF;
                NSUInteger age = bytes[4] & 0XFF;
                NSUInteger height = *((uint16_t *)(bytes+5)) & 0XFFFF;
                NSUInteger weight = bytes[7] & 0XFF;
                if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceUsrInfoFromoDev:Age:Height:Weight:)])
                {
                    [self.dataDelegate stkeyFobServiceUsrInfoFromoDev:gender Age:age Height:height Weight:weight];
                }
            } // if(dataBytes[2] == 0)
            
            if(dataBytes[2] == PACK_CMD_FUNCTIN_CM_MEA_DURA_AND_TIME) { // 测量时长+间隔
                uint8_t * bytes = (uint8_t *)[data bytes];
                uint8_t meaType = bytes[3];
                
                uint8_t noSlepMeasDura = bytes[4] & 0xFF;  // 非睡眠测量时长
                uint16_t noSlepMeasInterval = *((uint16_t *)(bytes + 5)) & 0xFFFF; // 非睡眠 测量间隔

                
                uint8_t slepMeasDura = bytes[7] & 0xFF;; // 睡眠期间测量时长
                uint16_t slepMeasInterval = *((uint16_t *)(bytes + 8)) & 0xFFFF;; // 睡眠期间测量间隔
                // 回调
                if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCSEMDevMeaDuration:MeaDuraofNoSlepPerd:MeaIntervOfNoSlepPerd:MeaDuraofInSlepPerd:MeaIntervInNoSlepPerd:)]) 
                {
                    [self.dataDelegate stkeyFobServiceCSEMDevMeaDuration:meaType
                                                     MeaDuraofNoSlepPerd:noSlepMeasDura
                                                   MeaIntervOfNoSlepPerd:noSlepMeasInterval
                                                     MeaDuraofInSlepPerd:slepMeasDura
                                                   MeaIntervInNoSlepPerd:slepMeasInterval];
                }
                
            }//  if(dataBytes[2] == 1)
            
            if (dataBytes[2] == PACK_CMD_FUNCTIN_CM_DEVICE_ALGORITHM) { // 算法类型
                // Algorithm Type
                uint8_t * bytes = (uint8_t *)[data bytes];
                uint8_t algorithmType = bytes[3]; // 0 凌拓算法, 1 CM算法
                
                //
                if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCSEMalgorithmType:)])
                {
                    [self.dataDelegate stkeyFobServiceCSEMalgorithmType:algorithmType];
                }
            }
            
            if (dataBytes[2] == PACK_CMD_FUNCTIN_LED_MEA) { // led单测的状态
                uint8_t on = dataBytes[3]; // 当前是 开/关
                uint8_t led = dataBytes[4];
                uint8_t current = dataBytes[5]; // 电流
                uint8_t autoDim =  dataBytes[6]; // 自动调光
                uint8_t freq = dataBytes[7]; // 采样频率
                // stkeyFobServiceLedStateReport
                if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceLedStateReport:Led:Current:AutoDim:Freq:)])
                {
                    [self.dataDelegate stkeyFobServiceLedStateReport:on>0 Led:led Current:current AutoDim:autoDim Freq:freq];
                }
            }
            
        }
            break;
        case DEVICE_RESPONSE_LAST_ACTIVITY: // 单次最后的活动 0xC8
        case DEVICE_RESPONSE_HIS_ACTIVITY: // 活动历史数据 0xca
        {
            CAnAlgGrandActivity *cmActivity = [[CAnAlgGrandActivity alloc]initWithData:data];
            
            if(dataBytes[1] == DEVICE_RESPONSE_LAST_ACTIVITY) { // 单次最后 下发0x5c单次回调
                if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceLastActivity:)])
                {
                    [self.dataDelegate stkeyFobServiceLastActivity:cmActivity];
                }
            }
            
            // 每天晚上 0 点重置活动数据，重置前保存一条当天最终的活动数据
            if (dataBytes[1] == DEVICE_RESPONSE_HIS_ACTIVITY && [self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:cmActivity];
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_LAST_ACTIVITY_2://0xD3 最后的活动上报2
        case DEVICE_RESPONSE_HIS_ACTIVITY_2: // 活动 在活动2历史中上报 格式和 0xD3相同
        {
            CAnAlgGrandActivity2 *csemActivity2 = [[CAnAlgGrandActivity2 alloc]initWithData:data];
            
            if(dataBytes[1] == DEVICE_RESPONSE_LAST_ACTIVITY_2) { // 单次最后 下发0x5c单次回调
                if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceLastActivity2:)])
                {
                    [self.dataDelegate stkeyFobServiceLastActivity2:csemActivity2];
                }
            }
            
            // 每天晚上 0 点重置活动数据，重置前保存一条当天最终的活动数据
            if (dataBytes[1] == DEVICE_RESPONSE_HIS_ACTIVITY_2 && [self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:csemActivity2];
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_CM_REALMEAS_DATA:// 0xcb csem设备 实时测量数据
        {
            CAnAlgRealMeasure *realMeasu = [[CAnAlgRealMeasure alloc]initWithData:data];
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCSEMRealMeasu:)])
            {
                [self.dataDelegate stkeyFobServiceCSEMRealMeasu:realMeasu];
            }
            // 兼容旧协议 0x83的回调
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceRealtimeHRV:BloodOxygen:HeartRate:Status:)] ) {
                [self.dataDelegate stkeyFobServiceRealtimeHRV:realMeasu.hrv  BloodOxygen:realMeasu.spo2 HeartRate:realMeasu.heartRate Status:realMeasu.dataStatus];
            }
            
        }
            break;
        case DEVICE_RESPONSE_ACT_SWIM_SLEEP_HIS_CNT: // 活动+游泳+睡眠 历史数量
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            NSUInteger count = *( (uint16_t *)(bytes+2) );
            
            uint32_t minUUid = 0;
            uint32_t maxUUid = 0;
            
            memcpy((void *)(&minUUid) ,bytes+4 , sizeof(uint8_t) * 3);
            memcpy((void *)(&maxUUid),  bytes+7, sizeof(uint8_t) * 3);
            
            DebugNSLog(@"0xC2 data:%@", data);
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHisCntOfActivityAndSwimAndSleep:MinUUid:MaxUUid:)])
            {
                [self.dataDelegate stkeyFobServiceHisCntOfActivityAndSwimAndSleep:count MinUUid:minUUid MaxUUid:maxUUid];
            }
            
        }
            break;
        case DEVICE_RESPONSE_AUTO_DETEC_ACTIVITY_DATA:// 0xc3
        {
            // 活动自检数据
            CAnAlgAutoDetecActivity *activity = [[CAnAlgAutoDetecActivity alloc]initWithData:data];
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:activity];
            }
        }
            break;
            
        case DEVICE_RESPONSE_AUTO_DETEC_SWIM_DATA: // 0xc4 自检游泳
        {
//            SRcsemAutoDetecSWim *swim = [[SRcsemAutoDetecSWim alloc]initWithData:data];
//            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
//                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:swim];
//            }
        }
            break;
        case DEVICE_RESPONSE_ACTIVITY_DURIN_EXERCISE:// 0xc5 锻炼数据 历史上报
        {
            CAnAlgExerData *exerData = [[CAnAlgExerData alloc]initWithData:data];
            
            
            if ( [self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] )
            {
                // 历史终回调
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:exerData];
            }
          
            
        }
            break;
        case DEVICE_RESPONSE_ACTIVITY_REALTIME_DUR_EXER:// 0xcd 锻炼 实时上报
        {
            CAnAlgRltExerData *exerRltData = [[CAnAlgRltExerData alloc]initWithData:data];
            if ( [self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemRealtimeWorkoutData:)] )
            {
                // 锻炼实时回调
                [self.dataDelegate stkeyFobServiceCsemRealtimeWorkoutData:exerRltData];
            }
        }
            break;
        case DEVICE_RESPONSE_SWIM_SUM://0xc6 游泳汇总数据
        {
            CAnAlgSwimSumData *swimSum = [[CAnAlgSwimSumData alloc]initWithData:data];
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:swimSum];
            }

        }
            break;
        case DEVICE_RESPONSE_SWIM_SINGLE_LAP :// 0xC7 游泳单圈
        {
            CAnAlgSwimLapData *swimLapData = [[CAnAlgSwimLapData alloc]initWithData:data];
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:swimLapData];
            }
        }
            break;
        case DEVICE_RESPONSE_EXER_VITAL_SIGNS:// 0xCC 锻炼中的生命体征
        {
            CAnAlgExerVitalSignsData *exerVitalSign = [[CAnAlgExerVitalSignsData alloc]initWithData:data];
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:exerVitalSign];
            }
        }
            break;
        case DEVICE_RESPONSE_CM_SLEEP: // 0xC9 睡眠历史数据
        {
            CAnAlgSleep *csemSleep = [[CAnAlgSleep alloc]initWithData:data];
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:csemSleep];
            }
        }
            break;
        case DEVICE_RESPONSE_SKINTEMP_DUR_ASLEEP:// 0xCE
        {

            CAnAlgSkinTempAsleep *skinTmpObj = [[CAnAlgSkinTempAsleep alloc]initWith:data];
          
            // 回调
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:skinTmpObj];
            }
        }
            break;
        case DEVICE_RESPONSE_ACTIVITY_INTNSTY_HISDATA:
        {
            
            CAnAlgActIntnstyHisData *actIntHisData = [[CAnAlgActIntnstyHisData alloc]initWith:data];
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:actIntHisData];
            }

        }
            break;
            
        case DEVICE_RESPONSE_LED_MEA_DATA: // led单色
        {
            // stkeyFobServiceLedPPgDataRep
            uint8_t * bytes = (uint8_t *)[data bytes];
            NSMutableArray<NSNumber *> * resArray = [NSMutableArray new];
            
            uint8_t *startPoint = bytes+2;

            if (bytes[18] == 0) {
                
                for (int  i = 0; i < 4; i++) {
                    uint64_t value = *( (uint32_t *)(startPoint + i *sizeof(uint32_t)) );
                    [resArray addObject:@(value)];
                }
                
            }
            
            if (bytes[18] == 1) {
                for (int  i = 0; i < 4; i++) {
                    int32_t value = *( (int32_t *)(startPoint + i *sizeof(int32_t)) );
                    [resArray addObject:@(value)];
                }
            }
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceLedPPgDataRep:)])
            {
                [self.dataDelegate stkeyFobServiceLedPPgDataRep:resArray];
            }

            
            
        }
            break;
        case DEVICE_RESPONSE_PPG_STATA:
        {
//            uint8_t * bytes = (uint8_t *)[data bytes];
//            BOOL isWearing = bytes[2];
//            BOOL isDimming = bytes[3]; // 是否调光中
            
            CAPpgMeasureState *stateObj = [[CAPpgMeasureState alloc]initWith:data];
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServicePPGState:)] ) {
                [self.dataDelegate stkeyFobServicePPGState:stateObj];
            }
            
        }
            break;
        case DEVICE_RESPONSE_HIS_ERR_LOG:
        {
            CAnAlgDevErrLog *logObj = [[CAnAlgDevErrLog alloc]initWith:data];
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceCsemDeviceMeasurData:)] ) {
                [self.dataDelegate stkeyFobServiceCsemDeviceMeasurData:logObj];
            }
        }
            break;
        default:
            break;
    }
    
}

-(void)resetChargeState
{
    [_sdkTool reset];
}

#pragma mark --crc
// crc校验计算
+(uint8_t)crc8:(NSData *)packData {
    uint8_t crc = 0;
    Byte * bytes = (Byte *)[packData bytes];
    
    for (int i = 0; i < packData.length; i++) {
        crc = crc ^ (bytes[i]);
//        crc = crc & 0xffff;
    }
    return crc;
}

// crc校验检查
+(BOOL)crc8Checker:(NSData *) packData {
    if (YES) {
//        NSLog(@"CCL crc8Checker crc on");
        if (!( packData != nil && packData.length == CADATA_PKG_SIZE) ) {
            return NO;
        }
        Byte * dataBytes = (Byte *)[packData bytes];
        if (dataBytes[CAINDEX_PKG_HEAD] == CACMD_HEAD)
        {
            return  [self crc8:packData] == (dataBytes[CAINDEX_CRC] & 0xff);
        } else {
            return NO;
        }
    } else {
//        NSLog(@"CCL crc8Checker crc off");
        return true;
    }
}

@end
